home *** CD-ROM | disk | FTP | other *** search
- UNIT TP_Heap1;
-
- INTERFACE
- uses TP_DECL,
- {$IFDEF PC}
- Crt,
- {$ENDIF}
- TP_DEBUG;
-
- Procedure Append(VAR ThisList: HeapRecord; N: NoteRecPoint);
- Procedure InitNotePool;
- Procedure KillNotePool;
- Procedure KillNoteLists;
- Procedure KillList(VAR ThisList : HeapRecord);
- Function Empty(ThisList:HeapRecord):Boolean;
- Procedure InsertOnTop(VAR ThisList: HeapRecord; N : NoteRecPoint);
- Procedure Insert(VAR ThisList: HeapRecord; Nin, N: NoteRecPoint);
- Procedure Remove(VAR ThisList : HeapRecord; N : NoteRecPoint);
- Procedure FirstNote(ThisList:HeapRecord; VAR N:NoteRecPoint);
- Procedure LastNote(ThisList:HeapRecord; VAR N : NoteRecPoint);
- Procedure NextNote(N:NoteRecPoint; VAR P: NoteRecPoint);
- Procedure PrevNote(N:NoteRecPoint; VAR P : NoteRecPoint);
- Function GetFreeNote : NoteRecPoint;
- Procedure ResetNoteRec(N : NoteRecPoint);
- Procedure BringFreeNote(N:NoteRecPoint);
- Function EqualsNote(N:NoteRecPoint;ThisNote : Byte) : Boolean;
- Procedure Exchange(VAR ThisList : HeapRecord;
- VAR N1, N2 : NoteRecPoint);
- Function NoteList2String(ThisList : HeapRecord):String;
- Function ChordNoteList2String(ThisList : HeapRecord):String;
- IMPLEMENTATION
-
- (**********************************************************)
- Function Empty(ThisList:HeapRecord):Boolean;
- (**********************************************************)
- Begin
- (* Empty:=ThisList.Tail=nil; *) (* does not work properly yet, FIX !! *)
- Empty:=ThisList.Size=0;
- End;
-
- (********************************************************************)
- Procedure InsertOnTop(VAR ThisList: HeapRecord; N : NoteRecPoint);
- (********************************************************************)
- Begin
- With ThisList Do
- Begin
- if Tail=nil then
- Begin
- Tail:=N; N^.Next:=N; N^.Prev:=N;
- end
- else
- Begin
- N^.Next:=Tail^.Next; N^.Prev:=Tail;
- Tail^.Next^.Prev:=N;
- Tail^.Next:=N;
- End;
- Inc(Size);
- End;
- End;
-
- (**********************************************************)
- Procedure Append(VAR ThisList:HeapRecord; N: NoteRecPoint);
- (**********************************************************)
- begin
- with ThisList do
- Begin
- If Tail=nil Then
- Begin
- Tail:=N; N^.Next:=N; N^.Prev:=N;
- End
- Else
- Begin
- N^.Prev:=Tail;
- N^.Next:=Tail^.Next;
- Tail^.Next^.Prev:=N;
- Tail^.Next:=N;
- Tail:=N;
- End;
- Inc(Size);
- End;
- end;
-
- (*****************************************************************)
- Procedure Insert(VAR ThisList: HeapRecord; Nin, N: NoteRecPoint);
- (* inserts N BEFORE Nin !! *)
- (*****************************************************************)
- begin
- With ThisList Do
- Begin
- if (Tail = nil) then (* NoteList is empty *)
- InsertOnTop(ThisList,N)
- else
- if Nin=Tail^.Next Then (* N should be inserted in front of the first item in list ...*)
- (* Append(ThisList,N) *)
- InsertOnTop(ThisList,N)
- else
- Begin
- Nin^.Prev^.Next:=N;
- N^.Prev:=Nin^.Prev;
- Nin^.Prev:=N;
- N^.Next:=Nin;
- Inc(Size);
- End;
- End; (* with *)
- end;
-
- (**************************************************************)
- Procedure Remove(VAR ThisList : HeapRecord; N : NoteRecPoint);
- (**************************************************************)
- var
- P: NoteRecPoint;
- begin
- with ThisList Do
- Begin
- if Tail <> nil then
- begin
- P := Tail; (* pointer to Tail *)
- while (P^.Next<>N) and (P^.Next <> Tail) do P := P^.Next;
- if P^.Next = N then
- begin
- P^.Next := N^.Next;
- N^.Next^.Prev:=P;
- if Tail= N then if P = N then Tail:= nil else Tail:= N^.Prev;
- end; (* if *)
- end; (* if *)
- Dec(Size);
- end; (* with *)
- end;
-
- (*****************************************************)
- Procedure FirstNote(ThisList:HeapRecord; VAR N:NoteRecPoint);
- (*****************************************************)
- VAR c : CHAR;
- Begin
- N:=ThisList.Tail^.Next;
- If KeyPressed Then
- Begin
- c:=ReadKey;
- if c='q' then ErrorExit(17);
- End;
- End;
-
- (*****************************************************)
- Procedure LastNote(ThisList:HeapRecord; VAR N : NoteRecPoint);
- (*****************************************************)
- VAR c : CHAR;
- Begin
- N:=ThisList.Tail;
- If KeyPressed Then
- Begin
- c:=ReadKey;
- if c='q' then ErrorExit(17);
- End;
- End;
-
- (*****************************************************)
- Procedure NextNote(N:NoteRecPoint; VAR P: NoteRecPoint);
- (*****************************************************)
- VAR c : CHAR;
- Begin
- P:=N^.Next;
- If KeyPressed Then
- Begin
- c:=ReadKey;
- if c='q' then ErrorExit(17);
- End;
- End;
-
- (*****************************************************)
- Procedure PrevNote(N:NoteRecPoint; VAR P : NoteRecPoint);
- (*****************************************************)
- Begin
- P:=N^.Prev;
- End;
-
- (***************************************************)
- Procedure ResetNoteRec(N : NoteRecPoint);
- (***************************************************)
- Begin
- FillChar(N^,SizeOf(NoteRecord),0);
- End;
-
-
- (*****************************************************)
- Function GetFreeNote : NoteRecPoint;
- (*****************************************************)
- VAR N : NoteRecPoint;
- Begin
- With NotePool Do
- If Size>0 then
- Begin N:=Tail; Remove(NotePool,N); ResetNoteRec(N); end
- else
- ErrorExit(10);
- GetFreeNote:=N;
- End;
-
- (*****************************************************)
- Procedure BringFreeNote(N:NoteRecPoint);
- (*****************************************************)
- Begin
- Append(NotePool,N);
- End;
-
- (*************************************************************)
- Function EqualsNote(N:NoteRecPoint;ThisNote : Byte) : Boolean;
- (*************************************************************)
- Begin
- If N^.NoteVal=ThisNote then
- EqualsNote:=TRUE
- else
- EqualsNote:=FALSE;
- End;
-
-
- (*************************)
- Procedure InitNotePool;
- (*************************)
- CONST POOLSIZE=200;
-
- VAR
- N : NoteRecPoint;
-
- Begin
- for i:=1 to POOLSIZE do
- begin
- If MaxAvail>SizeOf(NoteRecord) Then
- GetMem(N,SizeOf(NoteRecord))
- Else ErrorExit(9);
- Append(NotePool,N);
- end;
- End; (* InitNoteHeap *)
-
- (*************************)
- Procedure KillNotePool;
- (*************************)
- Begin
- KillList(NotePool);
- End;
-
- (*************************)
- Procedure KillNoteLists;
- (*************************)
- VAR I : Integer;
- Begin
- for i:=1to 16 do
- with TrackArray[i] do
- if NoteList.Tail<>NIL Then KillList(NoteList);
- KillList(NotePool);
- End;
-
-
- (***********************************************)
- Procedure KillList(VAR ThisList : HeapRecord);
- (***********************************************)
- VAR
- N,P : NoteRecPoint;
- Begin
- LastNote(ThisList,P);
- While NOT Empty(ThisList) do
- begin
- N:=P^.Next;
- Remove(ThisList,N);
- FreeMem(N,SizeOf(NoteRecord));
- end;
- End; (* InitNoteHeap *)
-
-
- (***********************************************************)
- Function NoteList2String(ThisList : HeapRecord):String;
- (***********************************************************)
- Var Tmpstr,tmp : String;
- N,P : NoteRecPoint;
- Begin
- N:=ThisList.Tail^.Next;
- P:=N;
- Tmpstr:='';
- Repeat
- Case N^.Event OF
- NOTEON,NOTEOFF : Begin
- Str(N^.NoteVal,tmp);
- TmpStr:=Tmpstr+tmp+' ';
- End;
- Else TmpStr:=Tmpstr+'n ';
- End;
- NextNote(N,N)
- until N=P;
- NoteList2String:=TmpStr;
- End;
-
- (***********************************************************)
- Function ChordNoteList2String(ThisList : HeapRecord):String;
- (***********************************************************)
- Var Tmpstr,tmp : String;
- N,P : NoteRecPoint;
- Begin
- N:=ThisList.Tail^.Next;
- P:=N;
- Tmpstr:='';
- Repeat
- Case N^.Event OF
- NOTEON,NOTEOFF : Begin
- Str(N^.NoteVal,tmp);
- If N^.ChordNote Then
- TmpStr:=Tmpstr+'-- '
- Else
- TmpStr:=Tmpstr+tmp+' ';
- End;
- Else TmpStr:=Tmpstr+'n ';
- End;
- NextNote(N,N)
- until N=P;
- ChordNoteList2String:=TmpStr;
- End;
-
- (*************************************************)
- Procedure Exchange(VAR ThisList : HeapRecord;
- VAR N1, N2 : NoteRecPoint);
- (*************************************************)
- Var P1,P2,F : NoteRecPoint;
- Begin
- F:=ThisList.Tail^.Next; (* first item in notelist *)
- NextNote(N1,P1);
- NextNote(N2,P2);
- If P1=N2 Then
- If P2=N1 Then (* only two notes in the list *)
- With ThisList Do NextNote(Tail,Tail)
- Else
- Begin
- Remove(ThisList,N2);
- (*If N1=F Then Append(ThisList,N2) Else *)
- Insert(ThisList,N1,N2);
- Remove(ThisList,N1);
- If P2=F Then Append(ThisList,N1) Else Insert(ThisList,P2,N1);
- End
- Else
- Begin
- Remove(ThisList,N1);
- (* If N2=F Then Append(ThisList,N1) Else *)
- Insert(ThisList,N2,N1);
- Remove(ThisList,N2);
- If P1=F Then Append(ThisList,N2) Else Insert(ThisList,P1,N2);
- End;
- End; (* exchange *)
-
-
- Begin
- NotePool.Tail:=nil;
- NotePool.Size:=0;
- For i:=1 to 16 do with TrackArray[i].NoteList do
- Begin Size:=0; Tail:=NIL; End;
- End.
-